package com.yjm.test.Spring5.ch5.aop;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;

import com.yjm.test.Spring5.ch5.Guitar;

@Component
@Aspect
public class AuditAdvice implements MethodBeforeAdvice  {
	@Pointcut("execution(* *sing*(com.yjm.test.Spring5.Guitar)) && args(guitar)")
	public void singExecutionAnnotation(Guitar guitar) {
	}
	@Pointcut("bean(john*)")
	public void isJohnAnnotation() {
	}
	
	
	public void simpleBeforeAdvice(JoinPoint joinPoint) {
		System.out.println("#Executing: " +
				joinPoint.getSignature().getDeclaringTypeName()
				+ joinPoint.getSignature().getName() );
	}
	
	@Before("singExecutionAnnotation(guitar) && isJohnAnnotation()")
	public void complexBeforeAdvice(JoinPoint joinPoint, Guitar guitar) {
		System.out.println("&Executing: " +
				joinPoint.getSignature().getDeclaringTypeName()
				+ joinPoint.getSignature().getName() + " Guitar:" + guitar.getBrand());
	}
	@Around("singExecutionAnnotation(guitar) ")
	public Object simpleAroundAdvice(ProceedingJoinPoint pjp, Guitar guitar) throws Throwable {
		System.out.println("*Before execution:" + pjp.getSignature().getDeclaringTypeName() + " " + pjp.getSignature().getName() + " arguments:" + guitar.getBrand());
		Object ret = pjp.proceed();
		System.out.println("*After execution:" + pjp.getSignature().getDeclaringTypeName() + " " + pjp.getSignature().getName() + " arguments:" + guitar.getBrand());
		return ret;
	}

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("@Executing: " + method);
	}
}
